(import
 (except (rnrs base)
         let-values
         map
         error)
 (only (guile)
       lambda* λ
       call-with-prompt
       abort-to-prompt
       make-prompt-tag))


;; Make a new prompt tag for use with call-with-prompt and
;; abort-to-prompt.
(let ([prompt-tag (make-prompt-tag 'handled-sigint)])
  ;; Call a thunk within a new prompt, using the tag.
  (call-with-prompt prompt-tag
    ;; Thunk takes no arguments.
    (λ ()
      ;; Install a SIGINT handler (ctrl+c).
      (sigaction SIGINT
        (λ (signal)
          (abort-to-prompt prompt-tag 1 2 3)))
      ;; Run an endless loop, which the user will interrupt.
      (let loop ([i 0])
        (display (simple-format #f "at i=~a\n" i))
        (usleep 500000)
        (loop (+ i 1))))

    ;; Handler: This is the continuation of the program, which is used
    ;; when aborted to the prompt. The first argument is the "state of
    ;; the computation begun when thunk was called, and ending with
    ;; the call to abort-to-prompt". That state of the computation is
    ;; itself a continuation. The other arguments are whatever is
    ;; passed by the abort-to-prompt call.
    (λ (_state val1 val2 val3)
      ;; Display the value, with which the abort was done.
      (display
       (simple-format
        #f "aborted to prompt with values: ~a\n"
        val3)))))
